#include "ipc.h"
#include "types.h"
#include <iostream>
#include <thread>
#include <chrono>
#include <termios.h>
#include <fcntl.h>
#include <mutex>
#include <unistd.h>

class AlgoProcess {
private:
    SystemState current_state = SystemState::IDLE;
    bool running = true;
    bool strike_occurred = false;

public:
    void run() {
        sd_journal_print(LOG_INFO, "击球检测与离线分析进程 启动");
        sd_journal_print(LOG_INFO, "按 's' 模拟击球 事件");

        // 启动消息接收线程
        std::thread msg_thread(&AlgoProcess::message_loop, this);
        sd_journal_print(LOG_INFO, "启动ALGO_SOCKET消息接收线程");
        // 启动按键检测线程
        std::thread key_thread(&AlgoProcess::keyboard_listener, this);
        sd_journal_print(LOG_INFO, "启动ALGO_SOCKET按键检测线程");
        msg_thread.join();
        key_thread.join();
    }

private:
    void message_loop() {
        Message msg;
        while (running) {
            if (receive_message(ALGO_SOCKET, msg)) {
                handle_message(msg);
            }
            std::this_thread::sleep_for(std::chrono::milliseconds(100));
        }
    }

    void handle_message(const Message& msg) {
        switch (msg.type) {
            case MessageType::STATE_CHANGE:
                {
                    current_state = msg.state;
                    if (current_state == SystemState::CAPTURE) {
                        strike_occurred = false;
                        sd_journal_print(LOG_INFO, "Algo: 进入采集状态, 等待击键事件");
                    } else if (current_state == SystemState::OFFLINE_PROCESSING) {
                        sd_journal_print(LOG_INFO, "Algo: 开始离线分析线程");
                        offline_processing();
                    }
                }
                break;

            case MessageType::HEARTBEAT:
                {// 响应心跳
                    Message response;
                    response.type = MessageType::HEARTBEAT;
                    response.timestamp = get_current_timestamp();
                    send_message(SUPERVISOR_SOCKET, response);
                    //sd_journal_print(LOG_INFO, "向状态控制进程发送心跳包");
                }
                break;

            default:
                break;
        }
    }

    void keyboard_listener() {
        // 设置非阻塞键盘输入
        int flags = fcntl(STDIN_FILENO, F_GETFL, 0);
        fcntl(STDIN_FILENO, F_SETFL, flags | O_NONBLOCK);

        while (running) {
            char c;
            if (read(STDIN_FILENO, &c, 1) == 1) {
                sd_journal_print(LOG_INFO, "从键盘收到  %c", c);
                if (c == 's' && current_state == SystemState::CAPTURE && !strike_occurred) {
                    strike_occurred = true;
                    trigger_strike();
                }
            }
            std::this_thread::sleep_for(std::chrono::milliseconds(100));
        }
    }

    void trigger_strike() {
        uint64_t timestamp = get_current_timestamp();
        sd_journal_print(LOG_INFO, "Strike detected at %ld", timestamp);

        // 发送击球事件给 supervisor
        Message msg;
        msg.type = MessageType::STRIKE_DETECTED;
        msg.strike.timestamp = timestamp;
        msg.timestamp = timestamp;
        send_message(SUPERVISOR_SOCKET, msg);
    }

    void offline_processing() {
        // 模拟离线分析
        std::cout << "Starting offline analysis...\n";
        
        // 模拟处理时间
        std::this_thread::sleep_for(std::chrono::seconds(3));
        
        std::cout << "Offline analysis completed\n";
        
        // 通知 supervisor 处理完成
        Message msg;
        msg.type = MessageType::PROCESSING_FINISHED;
        msg.timestamp = get_current_timestamp();
        send_message(SUPERVISOR_SOCKET, msg);
        //sd_journal_print(LOG_INFO, "向状态控制进程发送离线完成数据包");
    }

    uint64_t get_current_timestamp() {
        auto now = std::chrono::system_clock::now();
        auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(
            now.time_since_epoch()
        );
        return ms.count();
    }
};

int main() {
    try {
        AlgoProcess process;
        process.run();
    } catch (const std::exception& e) {
        std::cerr << "Algo process error: " << e.what() << "\n";
        return 1;
    }
    return 0;
}